%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "syntax.tab.h"


/*Manual P38*/

typedef struct YYLTYPE
{
  int first_line;
  int first_column;
  int last_line;
  int last_column;
}YYLTYPE;

YYLTYPE yylloc;

int yycolumn = 1; 

#define YY_USER_ACTION \
yylloc.first_line = yylloc.last_line = yylineno; \
yylloc.first_column = yycolumn; \
yylloc.last_column = yycolumn + yyleng - 1; \
yycolumn += yyleng; 
/*End*/


%}

%option yylineno

INT_CORRECT (0|[1-9][0-9]*)
FLOAT_CORRECT [0-9]*\.?[0-9]+|[0-9]+\.
ID_CORRECT [a-zA-Z_][a-zA-Z0-9_]*
SPACE [ \r\t]+

SEMI ;
COMMA ,
ASSIGNOP =
RELOP >|<|>=|<=|==|!=
PLUS \+
MINUS \-
STAR \*
DIV \/
AND &&
OR \|\|
DOT \.
NOT !
TYPE int|float
LP \(
RP \)
LB \[
RB \]
LC \{
RC \}
STRUCT struct
RETURN return
IF if
ELSE else
WHILE while

INT_ERROR 0[0-9]+|([0-9]*[a-zA-Z]+)+
FLOAT_ERROR \.[0-9]+|[0-9]+\.|{INT_ERROR}\.[0-9]+
ID_ERROR [0-9]+[a-zA-Z_]+

%%

{SPACE}         { }

{TYPE}          { yylval.type_node = newNode(yylineno, 0, "TYPE", NULL); return TYPE; }

{STRUCT}        { yylval.type_node = newNode(yylineno, 0, "STRUCT", NULL); return STRUCT; }
{RETURN}        { yylval.type_node = newNode(yylineno, 0, "RETURN", NULL); return RETURN; }
{IF}            { yylval.type_node = newNode(yylineno, 0, "IF", NULL); return IF; }
{ELSE}          { yylval.type_node = newNode(yylineno, 0, "ELSE", NULL); return ELSE; }
{WHILE}         { yylval.type_node = newNode(yylineno, 0, "WHILE", NULL); return WHILE; }

{SEMI}          { yylval.type_node = newNode(yylineno, 0, "SEMI", NULL); return SEMI; }
{COMMA}         { yylval.type_node = newNode(yylineno, 0, "COMMA", NULL); return COMMA; }
{ASSIGNOP}      { yylval.type_node = newNode(yylineno, 0, "ASSIGNOP", NULL); return ASSIGNOP; }
{RELOP}         { yylval.type_node = newNode(yylineno, 0, "RELOP", NULL); return RELOP; }
{PLUS}          { yylval.type_node = newNode(yylineno, 0, "PLUS", NULL); return PLUS; }
{MINUS}         { yylval.type_node = newNode(yylineno, 0, "MINUS", NULL); return MINUS; }
{STAR}          { yylval.type_node = newNode(yylineno, 0, "STAR", NULL); return STAR; }
{DIV}           { yylval.type_node = newNode(yylineno, 0, "DIV", NULL); return DIV; }
{AND}           { yylval.type_node = newNode(yylineno, 0, "AND", NULL); return AND; }
{OR}            { yylval.type_node = newNode(yylineno, 0, "OR", NULL); return OR; }
{DOT}           { yylval.type_node = newNode(yylineno, 0, "DOT", NULL); return DOT; }
{NOT}           { yylval.type_node = newNode(yylineno, 0, "NOT", NULL); return NOT; }

{LP}            { yylval.type_node = newNode(yylineno, 0, "LP", NULL); return LP; }
{RP}            { yylval.type_node = newNode(yylineno, 0, "RP", NULL); return RP; }
{LB}            { yylval.type_node = newNode(yylineno, 0, "LB", NULL); return LB; }
{RB}            { yylval.type_node = newNode(yylineno, 0, "RB", NULL); return RB; }
{LC}            { yylval.type_node = newNode(yylineno, 0, "LC", NULL); return LC; }
{RC}            { yylval.type_node = newNode(yylineno, 0, "RC", NULL); return RC; }

{INT_CORRECT}           { yylval.type_node = newNode(yylineno, 0, "INT", NULL); return INT_CORRECT; }
{FLOAT_CORRECT}         { yylval.type_node = newNode(yylineno, 0, "FLOAT", NULL); return FLOAT_CORRECT; }
{ID_CORRECT}            { yylval.type_node = newNode(yylineno, 0, "ID", NULL); return ID_CORRECT; }

{ID_ERROR}      { yylval.type_node = newNode(yylineno, 0, "ID", NULL); return ID_ERROR; }
{INT_ERROR}     { yylval.type_node = newNode(yylineno, 0, "ID", NULL); return INT_ERROR; }
{FLOAT_ERROR}   { yylval.type_node = newNode(yylineno, 0, "ID", NULL); return FLOAT_ERROR; }

\n              { yycolumn = 1; }

.               { isFalse = 1; printf("Error type A at Line %d: Mysterious characters \'%s\'\n", yylineno, yytext); }

%%

